import { Link, Construction, FileRemoved } from '@brillout/docpress'
import { IconLocal, IconGlobal } from '../../components'

Detailed information about Vike's config files.

For a list of configurations, see instead:
 - <Link href="/settings" />
 - <Link href="/hooks" />


## `+` files

You configure your Vike app by creating `+` files.

For example, you can set the <Link href="/Page">`Page`</Link> and <Link href="/Layout">`Layout`</Link> settings of a page by defining `+config.js`:

```ts
// /pages/product/@id/+config.ts

import type { Config } from 'vike/types'
import Page from './Page'
import Layout from './Layout'

export default {
  Page,
  Layout
} satisfies Config
```
```ts
// /pages/product/@id/Page.ts

// @detype-uncomment export default /* ... */
```
```ts
// /pages/product/@id/Layout.ts

// @detype-uncomment export default /* ... */
```

For more convenience, you can define following `+` files instead:

```yaml
/pages/product/@id/+config.ts # [!code --]
/pages/product/@id/Page.tsx # [!code --]
/pages/product/@id/Layout.tsx # [!code --]
/pages/product/@id/+Page.tsx # [!code ++]
/pages/product/@id/+Layout.tsx # [!code ++]
```

Vike automatically picks up `+` file — it doesn't make any difference whether you define `Page`/`Layout` via `+Page.jsx`/`+Layout.jsx`, or via `+config.js > export default { Page, Layout }`.

> Except of `+config.js`, any `+` file corresponds to a Vike <Link href="/settings">setting</Link> or <Link href="/hooks">hook</Link>.


## Inheritance

Vike comes with a powerful config inheritance system that enables great flexibility and control.

### Basics

You can apply configurations to all pages, a group of pages, or only one page. For example:

```yaml
pages/(marketing)/index/+Page.jsx    # URL: /
pages/(marketing)/about/+Page.jsx    # URL: /about
# Layout for marketing pages
pages/(marketing)/+Layout.jsx

pages/admin-panel/index/+Page.jsx    # URL: /admin-panel
pages/admin-panel/users/+Page.jsx    # URL: /admin-panel/users
# Layout for admin pages
pages/admin-panel/+Layout.jsx

pages/product/@id/+Page.jsx
# Layout for the product page
pages/product/@id/+Layout.jsx
```

> The directory `(marketing)` is ignored by Filesystem Routing, see <Link href="/routing#groups" />.

Where:

- `pages/(marketing)/+Layout.jsx` applies to all pages living at `pages/(marketing)/**`
- `pages/admin-panel/+Layout.jsx` applies to all pages living at `pages/admin-panel/**`
- `pages/product/@id/+Layout.jsx` applies to one page `pages/product/@id/+Page.jsx`
   > Technically, `pages/product/@id/+Layout.jsx` applies to all pages at `/pages/product/@id/**` but there is only one page living there.

### Defaults

You can set defaults and override them. For example:

```ts
// pages/+config.ts

import type { Config } from 'vike/types'

export default {
  // Disable SSR by default
  ssr: false
} satisfies Config
```

```ts
// pages/(marketing)/+config.ts

import type { Config } from 'vike/types'

export default {
  // Enable SSR for marketing pages
  ssr: true
} satisfies Config
```

> <Link href="#cumulative">Cumulative configs</Link> don't get overridden but accumulate instead (unless the filename extension <Link href="#default-js" doNotInferSectionTitle /> is used).

### Cumulative

A configuration is called *cumulative* when it can be defined multiple times.

For example, the <Link href="/Layout">`+Layout` setting</Link> is cumulative — a page can be wrapped by multiple `<Layout>` components.

```yaml
# Defines the outer layout
pages/+Layout.js
# Defines the inner layout (aka nested layout)
pages/(marketing)/+Layout.js
```

```jsx
<Layout>      ⟸ pages/+Layout.js
  <Layout>    ⟸ pages/(marketing)/+Layout.js
    <Page />
  </Layout>
</Layout>
```

The `pages/(marketing)/+Layout.js` file doesn't override `pages/+Layout.js` — instead, multiple `<Layout>` components nest within each other.

> You can control how cumulative configs inherit from parent directories by using the filename suffixes <Link href="#clear-js" doNotInferSectionTitle noBreadcrumb /> and <Link href="#default-js" doNotInferSectionTitle noBreadcrumb />.

In contrast, the <Link href="/title">`+title` setting</Link> isn't cumulative — a page can only have one title.

```yaml
# Defines the default title
pages/+title.js
# Defines the title of the product page, overriding pages/+title.js
pages/product/@id/+title.js
```

### `.clear.js`

The `.clear.js` filename suffix resets the inheritance chain of <Link href="#cumulative">cumulative configs</Link>, preventing configurations from parent directories from being inherited.

```yaml
pages/+Layout.jsx
# Inherits pages/+Layout.jsx
pages/product/@id/+Page.jsx

# This layout clears inheritance and starts fresh
pages/admin/+Layout.clear.jsx
# This layout will be added to the admin layout
pages/admin/dashboard/+Layout.jsx
# Only inherits the two admin layouts above
pages/admin/dashboard/users/+Page.jsx
```

> See also:
> - <Link href="#default-js" doNotInferSectionTitle />
> - <Link href="/file-env" noBreadcrumb />

### `.default.js`

The `.default.js` filename suffix makes a <Link href="#cumulative">cumulative configuration</Link> act as a fallback — it's only used when no child directory defines the configuration.

```yaml
# Default layout
pages/+Layout.default.jsx
# Inherits the default layout
pages/product/@id/+Page.jsx

# Overrides the default layout
pages/admin/+Layout.jsx
# Only inherits the admin layout
pages/admin/dashboard/+Page.jsx
```

> See also:
> - <Link href="#clear-js" doNotInferSectionTitle />
> - <Link href="/file-env" noBreadcrumb />

### Global

Some configurations are always *global*, while others can be *local* — we distinguish these two types of configurations and call a configuration either *global* or *local*:

- <IconGlobal/> **Global configuration** — always applies to all pages.

  For example, the <Link href="/base-url">Base URL setting</Link> is global: changing the Base URL affects your whole app (all your pages).

  A global config cannot be applied to only a subset of pages.

  > There isn't any config inheritance for global configs:
  >
  > ```yaml
  > # Defining +baseAssets for a single page doesn't make sense — Vike logs a warning
  > # since this +baseAssets.js file applies to all pages, not just this one.
  > /pages/about/+baseAssets.js
  > /pages/about/+Page.js
  > # No config inheritance — the +baseAssets.js file above also applies to this page.
  > /pages/index/+Page.js
  > ```

- <IconLocal/> **Local configuration** — can be defined on a per-page basis.

  For example, the <Link href="/title">`+title` setting</Link> is local, because each page can have a different title.

  > A local config can apply globally if defined at a global location:
  > ```ts
  > // pages/+config.ts
  >
  > import { Config } from 'vike/types'
  >
  > export default {
  >   // If it isn't overridden then this title applies to all pages (more precisely
  >   // speaking: it applies to all pages defined at pages/**)
  >   title: 'My App'
  > } satisfies Config
  > ```

### Groups

You can use <Link href="/routing#groups">page groups</Link> to better organize configuration inheritance.

### Powerful

You can use config inheritance for having multiple and completely different stacks within the same app. For example:

```ts
// pages/admin/+config.ts

// Configuration that applies to all admin pages.
//   pages/admin/income/+Page.vue
//   pages/admin/kpi/+Page.vue
//   ...

import type { Config } from 'vike/types'
import vue from 'vike-vue/config'
import telefunc from 'vike-telefunc/config'

// Vue + SPA + RPC
export default {
  ssr: false,
  extends: [vue, telefunc]
} satisfies Config
```

```ts
// pages/product/@id/+config.ts

// Configuration that applies to the product page.
//   pages/product/@id/+Page.tsx

import type { Config } from 'vike/types'
import react from 'vike-react/config'
import graphql from 'vike-react-apollo/config'

// React + SSR + GraphQL
export default {
  ssr: true,
  extends: [react, graphql]
} satisfies Config
```

```ts
// pages/(marketing)/+config.ts

// Configuration that applies to all marketing pages.
//   pages/index/+Page.vue
//   pages/about/+Page.vue
//   pages/jobs/+Page.vue
//   ...

import type { Config } from 'vike/types'
import vue from 'vike-vue/config'

// Vue + SSR
export default {
  ssr: true,
  extends: [vue]
} satisfies Config
```

This also enables you to experiment and/or progressively migrate your stack on a page-by-page basis.

> [There is currently a blocker](https://github.com/vikejs/vike/issues/1813) for being able to use `vike-vue` and `vike-react` within the same app.

> `vike-telefunc` doesn't exist yet: it's the upcoming integration that will enable you to use RPC for fetching initial data (instead of using <Link href="/data"><code>+data</code></Link>).


## Pointer imports

Internally, Vike transforms this:

```ts
// /pages/+config.ts
// Environment: config

import type { Config } from 'vike/types'
import Layout from '../layouts/LayoutDefault.jsx'

export default {
  Layout
} satisfies Config
```

Into:

```ts
// /pages/+config.ts
// Environment: config

import type { Config } from 'vike/types'
import Layout from '../layouts/LayoutDefault.jsx'// [!code --]
// @detype-replace Layout_ Layout
const Layout_ = 'import:../layouts/LayoutDefault.jsx:default'// [!code ++]

export default {
  Layout
} satisfies Config
```

This enables Vike to load the file `/pages/+config.js` without having to load `LayoutDefault.jsx`. This means that Vike can quickly load all your `+config.js` files without having to load any runtime code.

> These fake imports, which we call *pointer imports*, apply only to `+config.js` files. Imports in other `+` files are normal imports.

It's similar to when you import images:

```ts
import logo from '../images/logo.svg'
// When you import an image, you don't actually load it: you get a URL instead.
console.log(logo) // /assets/logo.svg
```

Vike transforms an import inside `+config.js` to be a pointer import if and only if the import resolves to a file that doesn't end with `.js`/`.ts`/`.mjs`/`.mts`/`.cjs`/`.cts`.

For example, an import that resolves to a `.jsx` or `.vue` file is transformed to be a pointer import:

```ts
// /pages/+config.ts
// Environment: config

import type { Config } from 'vike/types'
// Resolves to the file LayoutDefault.jsx (a .jsx file) => pointer import
import Layout from '../layouts/LayoutDefault'
// Resolves to the file ssr.js (a .js file) => normal import
import ssr from './ssr'

console.log(Layout) // import:../layouts/LayoutDefault:default
console.log(ssr) // false

export default {
  Layout,
  ssr
} satisfies Config
```
```ts
// /pages/ssr.ts
// Environment: config

export default false
```

> `.jsx` or `.vue` files are client/server runtime code (they usually aren't used for configuration). Thus Vike treats `.jsx` and `.vue` imports as pointer imports.

#### Config code isn't runtime code

The config code itself is never included in runtimes:

```ts
// /pages/some-page/+config.ts

// A CSS import in a config file doesn't have any effect. CSS should
// be imported in runtime files such as +Page.jsx instead.
import './some.css'

// This log is printed only when Vike loads this +config.ts file (at development and when
// building your app). This log isn't included in the client nor server runtime.
// Consequently, you won't see this log in production.
console.log("I will never be logged in production")
```

#### Manually mark pointer imports

You can manually mark an import to be a pointer import:

```ts
// /pages/+config.ts
// Environment: config

import ssr from './ssr' with { type: 'pointer' }
console.log(ssr) // import:./ssr:default
```

<Construction>The `with { type: 'pointer' }` import attribute isn't implement yet, see workaround at [#1500](https://github.com/vikejs/vike/issues/1500).</Construction>


## See also

- <Link href="/filesystem-routing" />
- <Link href="/routing#groups" />
- <Link href="/error/runtime-in-config" />
- <Link href="/file-env" />
